<?php
/*
+ --------------------------------------------------- +
|  Ineo Article Manager - Version 2.x
|  Copyright 2006-2007, Dan Cryer and William McGann
+ --------------------------------------------------- +

Ineo Article Manager is free software; you can redistribute it and/or modify
it under the terms of version 3 of the GNU General Public License as published by
the Free Software Foundation.

Ineo Article Manager is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Ineo; see the file License.txt.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

*/

/**
* Ineo - Libraries - Category Management
*  
* This library handles the category management functions of Ineo,
* including adding and removing categories, loading category data,
* loading article lists for a category, etc.
*
* @package		Ineo
* @subpackage   Libraries
* @author		Dan Cryer & William McGann
* @copyright	Dan Cryer & William McGann
* @version		1.0.0
*/
class ineo_lib_categories
{
    var $cache = array();

	/**
	* Constructor:
	*/
	function ineo_lib_categories( &$ineo )
	{
		$this->core     =& $ineo;
		$this->ipsclass =& $ineo->ipsclass;
	}
    
    /**
    * Load all categories into an array:
    */
    function load_all_cats( $order = 'category_order, category_name ASC' )
    {
        // Check cache:
        if( isset( $this->cache['load_all_cats'] ) )
        {
            return $this->cache['load_all_cats'];
        }
       
        // Grab data:
        $array = array(
						'select' => '*',
						'from'   => 'ineo_categories',
					  );
					  
		$this->ipsclass->DB->simple_construct( $array );
		$this->ipsclass->DB->simple_order( $order );
		$cats = $this->ipsclass->DB->simple_exec();
		
		// Create basic array:
		$categories = array();
		
		// Loop through to build an array:
		while( $res = $this->ipsclass->DB->fetch_row( $cats ) )
		{
		    $categories[$res['category_id']] = $res;
		}
		
		// Cache:
		$this->cache['load_all_cats'] = $categories;
		
		// Return:
		return $categories;
    }
    
    /**
    * ITT we recreate category cache. MOAR
    */
    function rebuild_cat_cache()
    {
    	$cat_array =& $this->get_categories();
		$this->ipsclass->cache['ineo_cats'] = array();
		$this->ipsclass->cache['ineo_cats'] = $cat_array;
		$this->ipsclass->update_cache( array( 'name' => 'ineo_cats', 'array' => 1, 'deletefirst' => 1 ) );
    }
    
    /**
    * Return a nested array of all categories.
    */
	function get_categories()
	{
		// Create a categories array
		$this->categories = array();
		
		// Load the "flat" categories array:
		$this->flat_cat_array = $this->load_all_cats();
		
		// Recurse!
		$this->get_categories_recurse( $this->categories, 0 );
		
		return $this->categories;
	}
	
	function get_categories_recurse( &$current_level_array, $check_for = 0 )
	{
		foreach( $this->flat_cat_array as $category )
		{
			if( $category['category_parent'] == $check_for )
			{
				$cat_id = $category['category_id'];
				
				$this->categories[$cat_id] = array('info' => $category,'children' => array());
				
				if( $check_for != 0 )
				{
					$this->categories[$cat_id]['parent'] =& $this->categories[$check_for];
				}
				
				$current_level_array[$cat_id] =& $this->categories[$cat_id];
				$this->get_categories_recurse($current_level_array[$cat_id]['children'],$cat_id);
			}
		}
	}
    
    /**
    * Load one specific category and return
    */
    function load_category_data( $cat_id )
    {
        if( is_array( $this->ipsclass->cache['ineo_cats'][$cat_id] ) )
		{
			return $this->ipsclass->cache['ineo_cats'][$cat_id]['info'];
		}
		else
		{
			return false;
		}
    }
    
    /**
    * Load a list of all of the articles inside a category:
    */
    function load_category_articles( $cat_id , $order , $start , $limit )
    {
        // Check cache:
        if( isset( $this->cache['cat_articles_'.$cat_id] ) )
        {
            return $this->cache['cat_articles_'.$cat_id];
        }
        
        // Build the query:
        $array = array(
						'select' => '*',
						'from'   => 'ineo_articles',
						'where'  => 'article_cat_id = '. $cat_id . ' AND article_is_queued = 0',
					  );
		$this->ipsclass->DB->simple_construct( $array );
		
		$this->ipsclass->DB->simple_order($order);
		
		// Add the order by:
		// $this->ipsclass->DB->simple_order( 'article_title ASC' );
		
		// Add limit:
		$this->ipsclass->DB->simple_limit( $start, $limit );
		$q = $this->ipsclass->DB->simple_exec();
		
		while( $art = $this->ipsclass->DB->fetch_row($q) )
		{
			$art['article_date'] = $this->ipsclass->get_date( $art['article_created_date'] , '' );
			$art['article_link'] = $this->core->libs['global']->make_article_url( $art['article_id'], $art['article_text_id'] );
		    $return[$art['article_id']] = $art;
		}
		
		// Cache:
		$this->cache['cat_articles_'.$cat_id] = $return;
		
		// Return:
		return $return;
    }
    
    /**
    * Count the number of articles in the category:
    */
    function category_count_articles( $cat_id )
    {
        $this->ipsclass->DB->simple_select( 'count(*) as cnt', 'ineo_articles', 'article_cat_id = ' . $cat_id );
	    $count = $this->ipsclass->DB->simple_exec();
	    $count = $this->ipsclass->DB->fetch_row( $count );
	    return $count['cnt'];
    }

	/**
	* Load all categories with a specific parent:
	*/
	
	function load_cats_by_parent( $parent_id )
	{
		$return = array();

		foreach( $this->ipsclass->cache['ineo_cats'] as $cat )
		{
			if( $cat['info']['category_parent'] == $parent_id )
			{
				if( $this->core->permissions->check('view',$cat['info']['category_id']) )
				{
					$return[$cat['info']['category_id']] = $cat;
				}
			}
		}
		
		if( count($return) != 0 )
		{
			return $return;
		}
		else
		{
			return false;
		}
	}
		
	function load_articles_page( $cat_id, $display_order = 'article_id DESC', $start = 0 )
	{
		// Setup start / limit point ( for pagination ):
		$start = ( empty($this->ipsclass->input['st']) ) ? $start : $this->ipsclass->input['st'];
		$limit = $this->ipsclass->vars['ineo_cat_artcount'];
		
		// Load all of the articles in the category:
		$articles = $this->load_category_articles( $cat_id , $display_order , $start , $limit );
		
		// Count number of articles in this category
		$art_count = $this->category_count_articles( $cat_id );
		
		// Load page jump:
		$links = $this->ipsclass->build_pagelinks( array( 'TOTAL_POSS' => $art_count,'PER_PAGE' => $limit,'CUR_ST_VAL' => $start, 'BASE_URL'    => $this->core->base_url.'showcat='. $cat_id) );
		
		return array($links,$articles);
	}
	
	function display_article_list( $catId , $cat , $display_order = 'article_id DESC' , $start = 0 )
	{
		// Setup start / limit point ( for pagination ):
		$start = ( empty($this->ipsclass->input['st']) ) ? $start : $this->ipsclass->input['st'];
		$limit = $this->ipsclass->vars['ineo_cat_artcount'];
		
		// Load all of the articles in the category:
		$articles = $this->load_category_articles( $catId , $display_order , $start , $limit );
		
		
		// Count number of articles in this category
		$art_count = $this->category_count_articles( $catId );
	  
		// Build pagination links:
	  $links = $this->ipsclass->build_pagelinks( array( 'TOTAL_POSS' => $art_count,
		                                                  'PER_PAGE' => $limit,
		                                                  'CUR_ST_VAL' => $start,
		                                                  'BASE_URL'    => $this->core->base_url.'showcat='
		                                                  . $catId,) );
		
		$list = '';
		
		$return  = '';
		
		if( is_array($articles) )
		{
			// Loop thru articles and build our listing:
			foreach( $articles as $art )
			{
				$art['article_date'] = $this->ipsclass->get_date( $art['article_created_date'] , '' );
				$art['article_url'] = $this->core->libs['global']->make_article_url( $art['article_id'], $art['article_text_id'] );
				$list .= $this->core->templates['articles']->art_row( $art );
			}
			
			$return .= $this->core->templates['categories']->cat_listing( $cat['category_name'] , $list , $links );
			
			$has_art = true;
		}
		else
		{
			$has_art = false;
		}
		
		if(!$has_cats and !$has_art) // check for feline paintings.
		{
			// output using main category listing template:
		  $return .= $this->core->templates['categories']->cat_listing( $cat['category_name'] , 'none' , 'none' );
		}
		
		return $return;
	}
	
	function get_article_count( &$cat )
	{
		$count = $cat['info']['category_articles'];
		
		if( is_array($cat['children']) and count($cat['children']) )
		{
		foreach( $cat['children'] as $subcat )
		{
			$count = $count + $this->get_article_count($subcat);
		}
		}
	
		return $count;
	}
	
	function update_article_count( $cat_id )
	{
		$cat_id = intval($cat_id);
		
		$update = array('category_articles' => $this->category_count_articles($cat_id));
		
		$this->ipsclass->DB->do_update('ineo_categories',$update,'category_id = '.$cat_id);
		$this->rebuild_cat_cache();
	}
	
	function build_nav_tree( $category )
	{
		$tree = array();
		$this->build_nav_tree_internal($category,$tree);
		
		$tree = array_reverse($tree);
		
		foreach($tree as $cat) // get it? GET IT? cat... tree?!
		{
			$this->core->libs['global']->nav_add($cat[0],'showcat='.$cat[1]);
		}
	}
	
	function build_nav_tree_internal( $category, &$tree )
	{
		$cat =& $this->ipsclass->cache['ineo_cats'][$category];
		
		$tree[] = array($cat['info']['category_name'],$category);
		
		if( $cat['info']['category_parent'] != 0 )
		{
			$this->build_nav_tree_internal( $cat['info']['category_parent'], $tree );
		}
	}
}

?>